﻿using System;
using System.Collections.Generic;
using System.Linq;
using W.Models.DataAccess;
using System.Linq.Expressions;
using W.Models.Utils;

namespace W.Component
{
    public abstract class ReservasComponent<TEntity> : ComponentBase<Reservas> where TEntity : Reservas
    {
        protected Response Response = new Response();

        protected List<TEntity> Get(Expression<Func<Reservas, bool>> r)
        {
            List<Reservas> CollectionBase = this.Model.Reservas.Where(r).ToList().FindAll(t => t.GetType() == typeof(TEntity));
            List<TEntity> Collection = CollectionBase.ConvertAll<TEntity>(t => (TEntity)(object)t);
            return Collection;
        }

        public List<TEntity> Get()
        {
            List<Reservas> CollectionBase = this.Model.Reservas.ToList().FindAll(t => t.GetType() == typeof(TEntity));
            List<TEntity> Collection = CollectionBase.ConvertAll<TEntity>(t => (TEntity)(object)t);
            return Collection;
        }

        private void UpdateEstado(int id, int idEstado)
        {
            Reservas Entity = this.Get(id);
            if (HasPermitions(Entity))
            {
                Entity.EstadosReserva = this.Model.EstadosReserva.SingleOrDefault(t => t.id == idEstado);
                this.Model.SaveChanges();
            }
        }

        public void Cancelado(int id)
        {
            this.UpdateEstado(id, 2);
        }

        public void Anulado(int id)
        {
            this.UpdateEstado(id, 3);
        }

        public void Registrado(int id)
        {
            this.UpdateEstado(id, 1);
        }

        public void Incumplido(int id)
        {
            this.UpdateEstado(id, 4);
        }

        public void HasNotTimeConfict(List<TEntity> Collection, Reservas Entity)
        {
            List<Reservas> Reservas = this.Casting(Collection);
            this.Response.Success = Reservas.Exists(t => t.inicio >= Entity.fin || t.fin <= Entity.inicio);

            if (!this.Response.Success)
            {
                this.Response.Message = "Conflicto de horario";
            }
        }

        private List<Reservas> Casting(List<TEntity> list)
        {
            List<Reservas> Collection = list.ConvertAll<Reservas>(t => (Reservas)(object)t);
            return Collection;
        }

        protected void IsValidDateTimes(Reservas Entity)
        {
            this.Response.Success = Entity.inicio < Entity.fin;
            if (!this.Response.Success)
                this.Response.Message = "Fechas no validas";

        }

        public override void Create(Reservas Entity)
        {
            Entity.Usuarios = this.Get<Usuarios>(CurrentUser.Id);
            Entity.EstadosReserva = this.Get<EstadosReserva>(Entity.EstadosReserva.id);

            base.Create(Entity);
        }

        public bool HasPermitions(Reservas Entity)
        {
            return Entity.Usuarios.username == CurrentUser.Name;
        }
    }
}
